package com.withouther.robot.rainingrobot.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpException;
import com.alibaba.fastjson.JSON;
import com.withouther.robot.rainingrobot.core.constants.AsrType;
import com.withouther.robot.rainingrobot.core.constants.RoleType;
import com.withouther.robot.rainingrobot.core.result.CallResult;
import com.withouther.robot.rainingrobot.core.websocket.AudioMessageWebScoket;
import com.withouther.robot.rainingrobot.model.AsrResultWord;
import com.withouther.robot.rainingrobot.service.AudioAsrService;
import com.withouther.robot.rainingrobot.service.RobotRecordService;
import com.withouther.robot.rainingrobot.util.WebScoketUtils;
import com.withouther.robot.rainingrobot.util.ai.asr.SpeechTranscriberUtil;
import com.withouther.robot.rainingrobot.util.ai.asr.listener.impl.SinowelAsrListener;
import com.withouther.robot.rainingrobot.util.ai.asr.model.MessageChange;
import com.withouther.robot.rainingrobot.util.ai.dialogue.model.BotResult;
import com.withouther.robot.rainingrobot.util.ai.tts.TTSAudioFactory;
import com.withouther.robot.rainingrobot.util.ai.tts.model.TTSParam;
import com.withouther.robot.rainingrobot.util.ai.tts.model.TTSResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * @ClassName AudioAsrService
 * @Auther: tzq
 * @Date: 2020/6/12 09:04
 * @Description:
 */

@Slf4j
@Service("audioAsrService")
@PropertySource(value = {"classpath:ai.properties", "classpath:config.properties"})
public class AudioAsrServiceImpl implements AudioAsrService {

    @Autowired
    private Environment environment;

    @Value("${asr.type}")
    private int asrType;

    @Value("${tts.file.path}")
    private String ttsPath;

    @Autowired
    private RobotRecordService robotRecordService;


    @Override
    public CallResult<Integer> startAsr(String id, int type, Map<String, Object> asrParameter) {
        String keyId = WebScoketUtils.getScoketKey(id, type);
        String path = WebScoketUtils.getAsrWebScoket(keyId).getFilePath(); //人
        ThreadUtil.execute(() -> {
            log.info("------------------ channleId ：" + keyId + "; role:" + RoleType.getRoleTypeName(type) + "； open ASR success");
            SinowelAsrListener listener = new SinowelAsrListener() {
                @Override
                public void onOpen() {
                }

                @Override
                public void onClose(int closeCode, String reason) {
                }

                @Override
                public void onMessage(String message) {
                    AsrResultWord asrResultWord = new AsrResultWord();
                    asrResultWord.setChannelId(id);
                    asrResultWord.setQuestion(message);
                    asrResultWord.setRecordId(IdUtil.objectId());
                    asrResultWord.setRoleType(type);
                    List<AsrResultWord> asrQuestions = new ArrayList<>();
                    asrQuestions.add(asrResultWord);
                    log.info("--------------------channleId + role :" + keyId + ";asrType name :" + AsrType.getAsrTypeName(asrType) + "; 返回文本：" + message);
                    try {
                        // 推送实时转写
                        AudioMessageWebScoket.sendMessage(keyId, JSON.toJSONString(asrResultWord));
                        BotResult botResult = robotRecordService.getDialogue(message);
                        TTSParam ttsParam = new TTSParam();
                        ttsParam.setText(botResult.getText());
                        TTSResult ttsResult = TTSAudioFactory.getFactory().ttsAction(ttsParam, AsrType.ALI);
                        if ("on".equals(WebScoketUtils.intentSwitchMap.get(keyId))) {
                            WebScoketUtils.userMap.put(keyId, ttsResult.getFilePath());
                        }
                    } catch (HttpException e) {
                        e.printStackTrace();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onMessage(ByteBuffer message) {
                }

                /**
                 * 字字识别
                 * @param messageChange
                 */
                @Override
                public void onMessageChange(MessageChange messageChange) {

                }
            };
            try {
                log.info("channelId:" + id + "asrType name :" + AsrType.getAsrTypeName(asrType));
                // 开启asr
                openAsr(keyId, asrType, path, listener, asrParameter);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        return null;
    }

    @Override
    public boolean openAsr(String keyId, int asrType, String path, SinowelAsrListener listener, Map<String, Object> asrParameter) throws Exception {
        switch (asrType) {
            case AsrType.ALI:
                log.info("open start ali ASR success keyId:" + keyId);
                String aliAppKey = environment.getProperty("ali.asr.appKey");
                String aliAccessKey = environment.getProperty("ali.accessKey");
                String aliAccessSecret = environment.getProperty("ali.accessSecret");
                SpeechTranscriberUtil speechTranscriberUtil = new SpeechTranscriberUtil(aliAppKey, aliAccessKey, aliAccessSecret, "", asrParameter);
                speechTranscriberUtil.start(keyId, path, listener);
                break;
            case AsrType.BAIDU:
                break;
            case AsrType.TX:
                break;
            case AsrType.SBC:
                break;
            default:
                break;
        }
        return true;
    }
}

